#pragma once

#include <vector>
#include <set>
#include <map>
#include <string>

#include "Message.h"

#include "PC2Node.h"

#include "ManagerExecutor.h"

namespace PC2
{

class ResponseSet;
class TransactionInfoSet;

class PC2Coordinator
	: public PC2Node
{
public:
	PC2Coordinator(NodeInfo const& aID, std::vector<NodeInfo> const& aParticipantIDSet, char const* apDBPath);
	virtual ~PC2Coordinator();

public:
	void SetExecutor(ManagerExecutor* apExecutor);

public:
	int32_t Recovery(std::string* apData);
	void WaitAndRunOnce(uint32_t aTimeout);

protected:
	bool PerformNewAction( char const* apData, uint32_t aSize);
	bool PerformStoredAction(TransactionInfoSet* apInfoSet);

protected:
	bool HandleIncomingMessage(TransactionInfoSet* apInfoSet, uint32_t aTimeout);
	bool JudgePrepareResult(TransactionInfoSet* apInfoSet);

protected:
	void InitAndStorePrepareRequest(TransactionInfoSet* apInfoSet, char const* apData, uint32_t aSize);

protected:
	void HandlePrepareResponse(TransactionInfoSet* apInfoSet, Trans* apReceivedTrans);
	void HandleEcho(NodeInfo* apNodeInfo, Trans* apReceivedTrans);
	void HandleClientRequest(NodeInfo* apNodeInfo, char const* apData, uint32_t aSize, bool aIsBusy);

protected:
	void SendRequestForCurrentPhase(TransactionInfoSet* apInfoSet);
	std::set<uint32_t> FilterNotReceivedForCurrentPhase(TransactionInfoSet* apInfoSet);


protected:
	ManagerExecutor* m_pExecutor;

};


}